%% Calibration
% Runs the calibrations required for each of the models

function [cfg,indepvars, depvars] = OptimizeAfterMonteCarlo(cfg,exvars,depvars,indepvars,r)
%% Initialize some values before the actual iteration
temp.CalibrationOutput  = [];
cfg.StartingValues      = [];

for n = 1:length(cfg.MonteCarloFields)
    for m = 1: size(indepvars.(cfg.MonteCarloFields{n}),3)
        if indepvars.UseModes(r,m) | size(indepvars.(cfg.MonteCarloFields{n}),3)==1
        cfg.StartingValues(1,end+1)=...
        indepvars.(cfg.MonteCarloFields{n})(r,1,m);
        cfg.UseFields{n} = ['indepvars.' cfg.MonteCarloFields{n}];
        end
    end
end

%% Switch between the different models        
switch cfg.Model
    case {'ModelTravelOptimizedTW','ModelTravelLinearTW'}
        boundaries.low          = permute([ones([1 , length(cfg.StartingValues)])],[1 3 2])*0; 
        boundaries.high         = permute([ones([1 , length(cfg.StartingValues)])],[1 3 2])*10;
        modes                   = [true true true true];
                
    case {'ModelPoles'}
        boundaries.low          = permute([ones([1 , length(cfg.StartingValues)])],[1 3 2])*0; 
        boundaries.high         = permute([ones([1 , length(cfg.StartingValues)])],[1 3 2])*10;
        modes                   = [false true true true];
        
    case {'ModelSimple'}
        boundaries.low          = permute([0.2 0.8 0.6 0.65 0.1 0.4 0.7 0.6],[1 3 2]); 
        boundaries.high         = permute([2 1.2 1 1.05 2 1 1.3 1.8],[1 3 2]);
        modes                   = [true true true true];
        
    case {'ModelGcam'}
        boundaries.low          = permute([ones([1 , length(cfg.StartingValues)])],[1 3 2])*0; 
        boundaries.high         = permute([ones([1 , length(cfg.StartingValues)])],[1 3 2])*10;
        modes                   = [true true true true];
         
         if sum(strcmp(cfg.MonteCarloFields,'ShareWeight'))>0
         boundaries.low(find(strcmp(cfg.modes,'LDV')|strcmp(cfg.modes,'Car'))+find(strcmp(cfg.MonteCarloFields,'ShareWeight'))-1+sum(indepvars.UseModes(r,:))-4 ) = 1;
         boundaries.high(find(strcmp(cfg.modes,'LDV')|strcmp(cfg.modes,'Car'))+find(strcmp(cfg.MonteCarloFields,'ShareWeight'))-1+sum(indepvars.UseModes(r,:))-4) = 1;
         end

end
        %% Run it        
        if cfg.GeneticSolverT0
        [cfg,depvars,indepvars] = ... % Finestune the solution
            SelectSolver(cfg, exvars, depvars, indepvars, r, cfg.CalibrationYears,...
            cfg.UseFields, cfg.StartingValues,...
            'ga', boundaries.low, boundaries.high);
        end
        
        cfg.StartingValues      = [];
for n = 1:length(cfg.MonteCarloFields)
    for m = 1: size(indepvars.(cfg.MonteCarloFields{n}),3)
        if indepvars.UseModes(r,m) |size(indepvars.(cfg.MonteCarloFields{n}),3)==1
        cfg.StartingValues(1,end+1)=...
        indepvars.(cfg.MonteCarloFields{n})(r,1,m);
        cfg.UseFields{n} = ['indepvars.' cfg.MonteCarloFields{n}];
        end
    end
end
        
        [cfg,depvars,indepvars] = ... % Finestune the solution
            SelectSolver(cfg, exvars, depvars, indepvars, r, cfg.CalibrationYears,...
            cfg.UseFields, cfg.StartingValues,...
            cfg.Solver, boundaries.low, boundaries.high);
end